
// 00定义时候不要用包装对象类型
{
    let str1: string
    let str2: String

    str1 = 'hello'
    // str1 = new String('str1')  //报错 string不是包装对象类型 

    str2 = 'hello'
    str2 = new String('str2 可以')

    console.log(typeof str1)
    console.log(typeof str2)
}

// 01.any类型
{
    let a: any
    a = false
    // 任意类型
    // any类型可以赋值给任意类型
    let x: string
    x = a
    // 会污染x
}

// unknown 未知类型
{
    let b: unknown
    b = '111'
    b = 99
    b = false

    let y: string
    // y = b  //Type 'unknown' is not assignable to type 'string'.ts(2322)
    // 解决方法 第一种
    if (typeof b === 'string') {
        y = b
    }
    //  断言
    y = b as string
    // 断言的第二种写法 泛型
    y = <string>b
}

// string,any,unknown区别
{
    let str1: string
    str1 = 'hello'
    str1.toUpperCase()

    let str2: any
    str2 = 'hello'
    str2.toUpperCase()

    let str3: unknown
    str3 = 'hello'
    // str3.toUpperCase() //'str3' is of type 'unknown'.ts(18046)
}
// never 类型 一般不用never去直接限制变量，因为没有意义 一般是限制函数的
{
    // 可以用于抛错
    // function demo(): never {
    //     throw new Error('程序运行异常')
    // }
    // console.log(demo())

    let a: string = 'hello'
    if (typeof a === 'string') {
        console.log(a.toUpperCase())
    } else {
        console.log(a) //此处a的类型为never 因为没有对应a的类型可以执行到该行
    }
}

// void 通常用于函数返回值声明：含义（函数返回值为空，调用者也不应依赖其返回值进行任何操作）
{
    function logMessage(msg: string): void {
        console.log(msg, 'msg')
    }
    logMessage('你好')
    /**
     * 注意：编码值没有return指定函数的返回值，logMessage函数没有显式返回值，但会有一个隐式返回值，就是undefined,
     * 即：虽然函数的返回类型为void，但也是可以接受undefined的，
     * 简单记：undefined是void可以接受的一种“空”
     *  */

    // 以下都ok
    function logMessage1(msg: string): void {
        console.log(msg, 'msg')
        return
    }
    function logMessage2(msg: string): void {
        console.log(msg, 'msg')
        return undefined
    }

    function demo1():void{
        console.log('@')
    }
    let result = demo1()
    // if(result){
    //     //An expression of type 'void' cannot be tested for truthiness.ts(1345)
    // }

    function demo2():undefined{
        console.log('@')
    }
    let result1 = demo2()
    if(result1){}

    /**
     * 总结：若函数范围类型为void，那么
     * 1.从语法上讲：函数是可以返回undefined的，至于显式返回，还是隐式返回，这都无所谓。
     * 2.从语义上讲：函数的调用者不应该关心函数返回的值，也不应依赖函数返回值进行任何操作，即使返回了undefined值。
     */
}

